package org.liveboardgames.agricola.vo.farm
{
	import com.adobe.cairngorm.vo.IValueObject;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ListCollectionView;
	
	import org.liveboardgames.agricola.vo.common.IResourceContainer;
	import org.liveboardgames.agricola.vo.common.Peep;
	import org.liveboardgames.common.dictionary.collections.HashCollection;
	import org.liveboardgames.common.dictionary.collections.IMap;

	[RemoteClass(alias="org.liveboardgames.agricola.domain.farm.FarmTile")]
	[Bindable]
	public class FarmTile implements IValueObject, IResourceContainer
	{
		/** The unique identifier of the tile, application-wide. */
		public var uniqueId:int;
		
		/** The id of the tile in the farm. */
		public var id:int;

		/** Has a value only if a peep is indeed on the tile.*/
		public var peeps:ListCollectionView;

		public var pasture:Pasture;

		/** Has a value only if there is a construction on the tile. */
		public var farmElement:String;

		/**
		 * The farm to which the tile belongs to.
		 * TODO: handle this in another way?
		 */
		public var farm:Farm;

		/**
		 * The resources that are on the tile (used to store the resources on
		 * a field for instance).
		 */
		public var resources:HashCollection;

		public function FarmTile(farm:Farm = null):void
		{
			this.farm = farm;
		}

		public function getPeep():Peep
		{
			var peep:Peep = null;
			if (this.peeps != null && this.peeps.length > 0)
			{
				peep = this.peeps.getItemAt(0) as Peep;
			}
			return peep;
		}

		public function removePeep(peep:Peep):void
		{
			if (this.peeps != null && this.peeps.length > 0)
			{
				var index:int = this.peeps.getItemIndex(peep);
				this.peeps.removeItemAt(index);
			}
		}

		public function addPeep(peep:Peep):void
		{
			if (this.peeps == null)
			{
				this.peeps = new ArrayCollection();
			}
			this.peeps.addItem(peep);
		}

		public function addResource(resource:String, quantity:int):void
		{
			if (this.resources == null)
			{
				resources = new HashCollection();
			}
			var currentQuantity:int = this.resources.getValue(resource) as int;
			this.resources.put(resource, Math.max(0, currentQuantity + quantity));
		}

		public function addResources(resources:IMap):void
		{
			if (resources != null)
			{
				for each (var resource:String in resources.getKeys())
				{
					var quantity:int = resources.getValue(resource);
					addResource(resource, quantity);
				}
			}
		}

		public function removeResources(resources:IMap):void
		{
			if (this.resources != null && resources != null)
			{
				for each (var resourceType:String in resources.getKeys())
				{
					var quantity:int = resources.getValue(resourceType);
					addResource(resourceType, -quantity);
				}
			}
		}

		public function setResource(type:String, quantity:int):void
		{
			if (this.resources == null)
			{
				resources = new HashCollection();
			}
			if (quantity > 0)
			{
				this.resources.put(type, quantity);
			}
			else
			{
				this.resources.remove(type);
			}
		}

		public function clone():FarmTile
		{
			var clone:FarmTile = new FarmTile(this.farm);

			clone.id = this.id;
			clone.farmElement = this.farmElement;

			return clone;
		}

		public function toString():String
		{
			return "Farm Tile " + this.id;
		}
	}
}